package com.ea.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.ea.common.constant.BaseNumConstant;
import com.ea.common.constant.RedisKeyConstants;
import com.ea.common.enums.BlockStatusEnums;
import com.ea.common.enums.GoodsStatusEnums;
import com.ea.common.enums.OperationResultCode;
import com.ea.common.enums.SysCfgKeyEnums;
import com.ea.common.enums.YesOrNoEnum;
import com.ea.common.exception.ServiceException;
import com.ea.common.util.IdWorker;
import com.ea.common.util.ObjectsUtil;
import com.ea.common.util.RedisUtil;
import com.ea.domain.dto.ElectricGoodCreateDTO;
import com.ea.domain.dto.ElectricGoodUpdateDTO;
import com.ea.domain.dto.ElectricSkuUpdateDTO;
import com.ea.domain.entity.ElectricGoodsInfo;
import com.ea.domain.entity.ElectricGoodsSkuInfo;
import com.ea.domain.entity.InventoryInfo;
import com.ea.domain.entity.SysBaseCfg;
import com.ea.domain.entity.SysBaseDictionary;
import com.ea.domain.query.BackElectricGoodsQueryDTO;
import com.ea.mapper.ElectricGoodsInfoMapper;
import com.ea.mapper.ElectricGoodsSkuInfoMapper;
import com.ea.mapper.InventoryInfoMapper;
import com.ea.mapper.SysBaseDictionaryMapper;
import com.ea.service.IElectricGoodsInfoService;
import com.ea.service.ISysBaseCfgService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


/**
 * @author NAME-L
 * @Description 后台货品管理方法实现类
 * @className ElectricGoodsInfoServiceImpl
 * @date 2022-12-06 21:13:30
 */
@Service
public class IElectricGoodsInfoServiceImpl implements IElectricGoodsInfoService {

    private static final Logger logger = LoggerFactory.getLogger(IElectricGoodsInfoServiceImpl.class);

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private ISysBaseCfgService sysBaseCfgService;

    @Autowired
    private ElectricGoodsInfoMapper goodsInfoMapper;

    @Autowired
    private ElectricGoodsSkuInfoMapper skuInfoMapper;

    @Autowired
    private InventoryInfoMapper inventoryInfoMapper;

    @Autowired
    private SysBaseDictionaryMapper baseDictionaryMapper;


    @Override
    public PageInfo<ElectricGoodsInfo> getGoodsInfoList(BackElectricGoodsQueryDTO queryDTO) {
        Integer pageIndex = queryDTO.getPageIndex() == null ? BaseNumConstant.NUM_1 : queryDTO.getPageIndex();
        Integer pageSize = queryDTO.getPageSize() == null ? BaseNumConstant.NUM_20 : queryDTO.getPageSize();
        PageHelper.startPage(pageIndex, pageSize);
        List<ElectricGoodsInfo> goodsInfoList = goodsInfoMapper.queryAllInfoList(queryDTO);
        return new PageInfo<>(goodsInfoList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createElectricGoods(ElectricGoodCreateDTO goodsCreateDTO) {
        if (goodsCreateDTO == null) {
            logger.error("添加货品异常，请重试");
            throw new ServiceException(OperationResultCode.CREATE_GOODS_PARAMETER_ERROR.getCode(), OperationResultCode.CREATE_GOODS_PARAMETER_ERROR.getMsg());
        }
        // 校验是否开启货品编码生成规则
        SysBaseCfg sysBaseCfg = sysBaseCfgService.getSysCfgByCfgKey(SysCfgKeyEnums.IS_OPEN_GOODS_GENERATE_RULE);

        ElectricGoodsInfo electricGoodsInfo = new ElectricGoodsInfo();
        electricGoodsInfo.setGoodsId(IdWorker.nextId());
        // 如果开启了生成规则
        if (sysBaseCfg == null || YesOrNoEnum.NO.getCode().toString().equals(sysBaseCfg.getCfgValue())) {
            electricGoodsInfo.setGoodsNo(goodsCreateDTO.getGoodsNo());
        } else if (YesOrNoEnum.YES.getCode().equals(Integer.valueOf(sysBaseCfg.getCfgValue()))) {
            SysBaseCfg goodsNumRule = sysBaseCfgService.getSysCfgByCfgKey(SysCfgKeyEnums.GOODS_GENERATE_NUM_RULE_PREFIX);
            String prefix;
            if (goodsNumRule == null) {
                prefix = "";
            } else {
                prefix = goodsNumRule.getCfgValue();
            }
            electricGoodsInfo.setGoodsNo(prefix + goodsCreateDTO.getGoodsNo());
        }
        electricGoodsInfo.setGoodsName(goodsCreateDTO.getGoodsName());
        electricGoodsInfo.setGoodsDesc(goodsCreateDTO.getGoodsDesc());
        electricGoodsInfo.setCateId(goodsCreateDTO.getCateId());
        if (goodsCreateDTO.getCateId() != null) {
            SysBaseDictionary dictionary = baseDictionaryMapper.selectSysDicByDicId(goodsCreateDTO.getCateId());
            electricGoodsInfo.setCateName(dictionary.getDicDesc());
        }
        electricGoodsInfo.setImgUrl(goodsCreateDTO.getImgUrl());
        // 判断货品是否有规格，有规格则取出规格放进sku
        List<ElectricGoodsSkuInfo> skuDTOList = goodsCreateDTO.getSkuDTOList();
        // 添加规格货品的集合
        List<ElectricGoodsSkuInfo> insertSkuDTOList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(skuDTOList)) {
            skuDTOList.forEach(skuDTO -> {
                skuDTO.setGoodsId(electricGoodsInfo.getGoodsId());
                skuDTO.setSkuId(IdWorker.nextId());
                skuDTO.setGoodsName(electricGoodsInfo.getGoodsName());
                skuDTO.setSkuBarcode(electricGoodsInfo.getGoodsNo() + "_" + skuDTO.getSkuBarcode());
                insertSkuDTOList.add(skuDTO);
            });
        } else {
            //没有规格则以该货品作为默认规格
            ElectricGoodsSkuInfo skuInfo = new ElectricGoodsSkuInfo();
            skuInfo.setSkuId(IdWorker.nextId());
            skuInfo.setGoodsId(electricGoodsInfo.getGoodsId());
            skuInfo.setGoodsName(electricGoodsInfo.getGoodsName());
            skuInfo.setSkuBarcode(electricGoodsInfo.getGoodsNo() + "-" + "默认规格");
            skuInfo.setSkuName(electricGoodsInfo.getGoodsName());
            // 为了避免没有规格时无法设置价格，所以将默认规格货品置为待上架状态，只有修改过价格后将其更改为已上架
            skuInfo.setStatus(GoodsStatusEnums.TAKE_DOWN.getCode());
            insertSkuDTOList.add(skuInfo);
        }
        // 将货品添加至货品表中
        goodsInfoMapper.insertElectricGoods(electricGoodsInfo);

        if (CollectionUtils.isNotEmpty(insertSkuDTOList)) {
            // 把货品规格批量添加进货品规格表中
            skuInfoMapper.skuInfoBatchInsert(insertSkuDTOList);
            List<InventoryInfo> inventoryInfoList = new ArrayList<>();
            insertSkuDTOList.forEach(skuDto -> {
                InventoryInfo inventoryInfo = new InventoryInfo();
                inventoryInfo.setSkuId(skuDto.getSkuId());
                inventoryInfo.setSkuAmount(BigDecimal.ZERO);
                inventoryInfo.setSkuName(skuDto.getSkuName());
                inventoryInfo.setSkuBarcode(skuDto.getSkuBarcode());
                inventoryInfoList.add(inventoryInfo);
            });
            // 添加库存
            inventoryInfoMapper.insertInventoryBatchList(inventoryInfoList);
        }
        // 判断请求参数里是否有规格货品，如果没有则取 insertSkuDTOList 里的第一个记录至redis中
        if (CollectionUtils.isEmpty(skuDTOList)) {
            // 将该货品规格 skuId放进redis中存储，用于后面更新状态时的校验
            redisUtil.sSet(RedisKeyConstants.SYS_NEES_PERFECT_GOODS_SKU, insertSkuDTOList.get(0).getSkuId().toString());
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void changeElectricGoods(ElectricGoodUpdateDTO updateDTO) {
        ElectricGoodsInfo goodsInfo = goodsInfoMapper.selectGoodsInfoByGoodsId(updateDTO.getGoodsId());
        if (BlockStatusEnums.BLOCK_UP.getCode().equals(goodsInfo.getStatus())) {
            throw new ServiceException(OperationResultCode.GOODS_IS_BLOCK_UP);
        }
        ElectricGoodsInfo updateGoodsInfo = new ElectricGoodsInfo();
        BeanUtil.copyProperties(updateDTO, updateGoodsInfo);
        if (updateDTO.getCateId() != null) {
            SysBaseDictionary dictionary = baseDictionaryMapper.selectSysDicByDicId(updateDTO.getCateId());
            updateGoodsInfo.setCateName(dictionary.getDicDesc());
        }
        // 修改货品信息时，如果更改了货品名称以及状态，那么需要同步修改该货品下所有规格的编号和状态
        List<ElectricGoodsSkuInfo> skuInfoList = skuInfoMapper.selectAllByGoodsId(updateDTO.getGoodsId());
        // 校验是否开启货品规格编码同步规则
        SysBaseCfg sysBaseCfg = sysBaseCfgService.getSysCfgByCfgKey(SysCfgKeyEnums.MODIFY_SKU_BARCODE_SAME_TIME);
        List<ElectricSkuUpdateDTO> updateDTOList = new ArrayList<>();

        for (ElectricGoodsSkuInfo skuInfo : skuInfoList) {
            ElectricSkuUpdateDTO skuUpdateDTO = new ElectricSkuUpdateDTO();
            // 如果货品名称修改，那么货品下所有规格的货品也需要修改对应字段值
            if (StringUtils.isNotEmpty(updateDTO.getGoodsName())) {
                skuUpdateDTO.setSkuId(skuInfo.getSkuId());
                skuUpdateDTO.setGoodsName(updateDTO.getGoodsName());
            }

            // 如果开启了该编码同步规则，那么需要同步修改该货品下所有规格的编号
            if (YesOrNoEnum.YES.getCode().equals(Integer.valueOf(sysBaseCfg.getCfgValue()))) {
                skuUpdateDTO.setSkuId(skuInfo.getSkuId());
                if (skuInfo.getSkuBarcode().contains(goodsInfo.getGoodsNo())) {
                    skuUpdateDTO.setSkuBarcode(skuInfo.getSkuBarcode().substring(skuInfo.getSkuBarcode().indexOf("_") + 1) + updateDTO.getGoodsNo());
                } else {
                    skuUpdateDTO.setSkuBarcode(updateDTO.getGoodsNo() + skuInfo.getSkuBarcode());
                }
            }

            if (!ObjectsUtil.isNullObject(updateDTO)) {
                updateDTOList.add(skuUpdateDTO);
            }
        }

        // 更新货品数据
        goodsInfoMapper.updateGoodsInfo(updateGoodsInfo);
        // 如果规格货品不为空，则更新规格货品信息
        if (CollectionUtils.isNotEmpty(updateDTOList)) {
            skuInfoMapper.updateSkuBatchList(updateDTOList);
        }
    }

    @Override
    public void changeElectricGoodsStatus(Long goodsId, Integer status) {
        logger.info("changeElectricGoodsStatus ====> goodsId:{} , status:{}", goodsId, status);
        // 如果修改货品状态为待上架或停用，那么该货品下所有规格都需要进行状态变更
        List<ElectricSkuUpdateDTO> updateDTOList = new ArrayList<>();
        ElectricGoodsInfo goodsInfo = goodsInfoMapper.selectGoodsInfoByGoodsId(goodsId);
        if (goodsInfo == null) {
            logger.error("货品id：{}，该货品不存在" , goodsId);
            throw new ServiceException(OperationResultCode.SYSTEM_ERROR);
        }
        if (BlockStatusEnums.BLOCK_UP.getCode().equals(goodsInfo.getIsBlock())) {
            throw new ServiceException(OperationResultCode.GOODS_IS_BLOCK_UP);
        }
        if (GoodsStatusEnums.TAKE_DOWN.getCode().equals(status)) {
            // 如果将货品变化为下架状态，那么所有的规格都将下架
            List<ElectricGoodsSkuInfo> skuInfoList = skuInfoMapper.selectAllByGoodsId(goodsId);
            if (CollectionUtils.isEmpty(skuInfoList)) {
                return;
            }
            for (ElectricGoodsSkuInfo skuInfo : skuInfoList) {
                ElectricSkuUpdateDTO skuUpdateDTO = new ElectricSkuUpdateDTO();
                skuUpdateDTO.setSkuId(skuInfo.getSkuId());
                skuUpdateDTO.setStatus(status);
                updateDTOList.add(skuUpdateDTO);
            }
        }
        // 如果修改货品状态为上架状态，那么需要确保该货品下存在任意一个规格是上架状态的规格货品后才可以将货品更改为上架状态
        if (GoodsStatusEnums.PUT_AWAY.getCode().equals(status)) {
            List<ElectricGoodsSkuInfo> skuInfoList = skuInfoMapper.selectAllByGoodsId(goodsId);
            List<ElectricGoodsSkuInfo> existsList = skuInfoList.stream().filter(sku -> GoodsStatusEnums.PUT_AWAY.getCode().equals(sku.getStatus())).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(existsList)) {
                throw new ServiceException(OperationResultCode.GOODS_HAS_NO_SKU_PUT_WAY.getCode() , String.format(OperationResultCode.GOODS_HAS_NO_SKU_PUT_WAY.getMsg(), goodsInfo.getGoodsName()));
            }
        }
        goodsInfoMapper.updateGoodsStatus(goodsId, status);
        if (CollectionUtils.isNotEmpty(updateDTOList)) {
            skuInfoMapper.updateSkuStatusBatchList(updateDTOList);
        }
    }

    @Override
    public void changeElectricBlockStatus(Long goodsId, Integer status) {
        logger.info("changeElectricBlockStatus ====> goodsId:{} , status:{}", goodsId, status);
        ElectricGoodsInfo goodsInfo = goodsInfoMapper.selectGoodsInfoByGoodsId(goodsId);
        if (goodsInfo == null) {
            logger.error("货品id：{}，该货品不存在" , goodsId);
            throw new ServiceException(OperationResultCode.SYSTEM_ERROR);
        }
        goodsInfoMapper.updateBlockStatus(goodsId, status);
    }
}
